package note_002;

/**
 * threadDemo123-----------------创建线程
 */
public class day07 {
    public static void main(String[] args) {


        /**
         * 多线程将程序的单一顺序执行方式改为可以让多个这样顺序执行的代码片段“同时”执行。
         * 这里并非真正的同时，而是并发的。
         * <p>
         * 创建线程的方式有两种，
         * 第一种:
         *      继承Thread重写run方法。在run方法中定义线程要执行的代码.
         *      1.创建类继承Thread重写run方法.
         *      2.在run方法中定义线程要执行的代码.
         *      3.Thread t1 = new MyThread1();//向上造型,多态,方法.
         *          t1.start();
         *                  第一种创建线程的方式优点为结构简单，便于使用---匿名内部类形式创建。
         *                  缺点主要有两个:
         *                      1.:由于Java是单继承的，这导致如果继承了Thread就无法在继承其他类，这在实际开发中很不便.因为我们
         *                          通常继承一个类的主要因素是为了复用方法。
         *
         *                      2.:定义线程的同时重写run方法将任务定义在了线程中，导致线程与任务是绑定在一起的，不利于线程的重用.
         * 第二种:
         *      创建线程的方式:实现Runnable接口单独定义线程任务
         */
        /*第二:  种创建线程的方式:实现Runnable接口单独定义线程任务  */
        /** Runnable 执行任务 */
//    //实例化线程要执行的任务
//    MyRunnable1 r1 = new MyRunnable1();//可以写一个内部类，匿名内部类有局限,创建一个类.
//    MyRunnable2 r2 = new MyRunnable2();
        /** Thread 线程 */
//    //创建两个线程
//    Thread t1 = new Thread(r1);
//    Thread t2 = new Thread(r2);
//        t1.start();//开始
//        t2.start();
        /**匿名内部类形式完成两种线程的创建方式.*/

        /**
         * Java中所有的代码都是有线程执行的，main方法也是不例外，JAM启动后会自动创建一条线程执行main方法。
         * 而JAM给这条线程取名为“main”，所以我们称执行main方法的线程为“主线程”.
         */

        /** static Thread currentThread(): 获取运行这个方法的线程.*/
        /*
            Thread提供的方法:
            static Thread currentThread()
            该方法可以获取运行这个方法的线程.
         */
        /**获取线程相关信息的一组方法.*///---------------------------------
//    Thread main = Thread.currentThread();
        /**获取线程的名字*/
//    String name = main.getName();

        /**获取线程的唯一标识  相当于ID*/
//    long id = main.getId();
        /**获取线程的优先级*/
//    int priority = main.getPriority();
        /**线程是否活着-------run()方法结束则死了*/
//    boolean isAlive = main.isAlive();
        /**是否为守护线程*/
//    boolean isDaemon = main.isDaemon();
        /**是否被中断了*/
//    boolean isInterrupted = main.isInterrupted();

        /**
         * 线程的优先级:
         * 线程有10个优秀级，分别对应整数1——10.其中1为最低优先级，10为最高优先级，5是默认值。
         * <p>
         * 线程start后就纳入到了线程调度器中统一管理，"线程不能主动索取CPU时间片"，只能被动分配。线程调度器
         * 会尽可能均匀分配时间片段给每一个线程。我们可以通过调整线程的优先级来改善一个线程获取CPU时间片的概率.
         * 线程优先级越高的线程获取CPU时间片的次数越多.
         */
        /** setPriority(int newPriority): 修改优先级 */
//        min.setPriority(Thread.MIN_PRIORITY);//部分(10,5,1)有常量可调用.
        /**
         * Thread提供了一个静态方法:
         * static void sleep(long ms)
         * 该方法可以让执行这个方法的线程处于阻塞状态指定毫秒，超时后线程会回到RUNNABLE状态等待分配时间片
         * 再次并发执行.
         * sleep控制时间不是太准确.
         */

        /**
         * 聊天室客户端
         */
     /*
        java.net.Socket : 套接字
        Socket封装了TCP协议的连接和通讯细节，使得我们使用他们可以很方便的与远端计算机建立连接并
        基于两个流(一个输入一个输出)的读写完成与远端计算机的数据交换从而实现对应的网络应用.
     */
    /*
        实例化Socket时需要传入两个参数:
        参数1：服务端的IP地址，如果连接本机则可以使用localhost

        参数2：服务端程序在服务端计算机上申请的服务端口。
        我们通过服务端的IP找到网络上服务端所在的计算机，通过端口找到该计算机上运行的服务端
        应用程序。

        实例化Socket的过程就是按照给定的地址与服务端建立连接的过程，如果连接失败则会抛出
        异常。
        */
    /*
        Socket提供的方法:
        OutputStream getOutputStream()
        获取一个字节输出流，通过这个流写出的字节会发送给远端计算机.

        注释:该方法无论调用多少次，返回的输出流始终是同一个.
        */
        //close操作中会给远端计算机发送断开信号。同时关闭对应的输入流与输出流.
        /**
         * 服务器
         */
    /*
        运行在服务端的ServerSocket主要用两个作用:
        1:向系统申请服务端口，客户端就是通过这个端口与服务器建立连接的
        2:监听服务端口，一口一个客户端建立连接就会创建一个Socket，使用这个Socket与客户端交互

        如果我们将Socket比喻为“电话”，则ServerSocket相当于是“总机”.
     */
    /*
        实例化ServerSocket时需要指定服务端口，客户端就是通过这个端口与服务端建立连接的
        该端口不能与当前系统的其他应用程序申请的端口一致，
        否则会抛出地址已被占用的异常:
        java.net.BindException:address already in use : JVM
        */
    /*
       ServerSocket提供的方法:
       Socket accept()
       该方法是一个阻塞方法，调用后会"卡住"，此时开始等待客户端的链接，一旦一个客户端
       建立链接时，该方法会立刻返回一个Socket。通过这个Socket就可以和该客户的交互了.
       */
        /**
         * ClientHandler 客户端处理器
         * 该类是一个线程任务，这就意味着每个这样的任务都是由一条线程执行的。
         * 该任务是负责与指定的客户端进行交互.
         */
    /*
       客户端如果正常调用了socket.close()与服务端断开连接时，服务端这里读取操作的方法
       readLine会返回null，表示客户端断开了连接，流读到了末尾，正常停止循环。
       但是如果客户端强制关闭了客户端，服务端无法正确得知客户端的断开就会抛出异常：
       java.net.SocketException:connection reset.连接重置
       */
    }

}
